/*
 * @Author: 张小平
 * @Date:   2025-05-01 
 * @Email:  qqshuqian@163.com 
 * @Copyright © 2024 aseyun. All rights reserved.
 */
import { suffix } from '@/framework-code/utils/constants'

const genId = () => {
  let id = (new Date()).getTime()
  let randomNumber = Math.floor(Math.random() * 100000)
  return `${id}${randomNumber}${suffix}`
}

const findById = (tree, id, deep = 0, pathIndex = '') => {
  let node = null
  let index = null
  let pathDeep = deep
  if (tree.id === id) {
    node = tree
  } else {
    pathDeep += 1
  }

  const treeChild = tree['child']
  const treeConditions = tree['conditions']

  if (treeChild) {
    pathIndex += '-,'
    const resTree = findById(treeChild, id, pathDeep, pathIndex)
    if (resTree.node) {
      node = resTree.node
      index = resTree.index
      pathDeep = resTree.pathDeep
      pathIndex = resTree.pathIndex
    } else {
      pathIndex = pathIndex.slice(0, -2)
    }
  }

  if (treeConditions && treeConditions.length) {
    for (let i = 0; i < treeConditions.length; i++) {
      const child = treeConditions[i]
      pathIndex += `${i},`
      const resTree = findById(child, id, pathDeep, pathIndex)
      if (resTree.node) {
        node = resTree.node
        index = i
        pathDeep = resTree.pathDeep
        pathIndex = resTree.pathIndex
        break
      } else {
        pathIndex = pathIndex.slice(0, -2)
      }
    }
  }

  return {
    node,
    index,
    pathDeep,
    pathIndex
  }
}

const getPathNode = (tree, currentNode, isParent = false) => {
  const {
    pathIndex
  } = currentNode

  let paths = pathIndex.slice(0, -1).split(',')
  let str = 'tree'

  let pathsLen = paths.length

  if (isParent) {
    pathsLen = paths.length - 1
  }

  if (paths.length) {
    for (let i = 0; i < pathsLen; i++) {
      if (paths[i] === '-') {
        str += `['child']`
      } else {
        str += `['conditions'][${paths[i]}]`
      }
    }
  }

  return {
    pathNode: eval(str),
    paths
  }
}

const deleteNode = (tree, currentNode) => {
  const { pathNode } = getPathNode(tree, currentNode, true)

  const {
    child
  } = currentNode.node

  if (child) {
    pathNode.child.id = child.id
    pathNode.child.type = child.type
    if (child.child) {
      pathNode.child.child = child.child
    } else {
      pathNode.child.child = null
    }
  } else {
    console.log(child, pathNode.child)
    pathNode.child = null
  }

  return tree
}

const setBranchTree = (branchChild, currentChild, branchPid) => {
  if (branchChild && branchChild.child) {
    setBranchTree(branchChild.child, currentChild, branchPid)
  } else if (branchChild) {
    currentChild.pid = branchChild.id
    branchChild.child = currentChild
    branchChild.pid = branchPid
  }
  return branchChild
}

const deleteBranch = (tree, currentNode) => {
  const { pathNode } = getPathNode(tree, currentNode, true)

  pathNode.conditions.splice(currentNode.index, 1)

  if (pathNode.conditions.length === 1) {
    const branchChild = pathNode.conditions[0].child
    const currentChild = pathNode.child
    const branchPid = pathNode.conditions[0].pid

    if (branchChild && currentChild) {
      const newBranchTree = setBranchTree(branchChild, currentChild, branchPid)
      pathNode.child = newBranchTree
    }
    pathNode.conditions = null

    const {
      child,
      id,
      type
    } = pathNode.child

    pathNode.child = child
    pathNode.id = id
    pathNode.type = type
  }

  return tree
}

const addNode = (tree, currentNode, newNode) => {
  const { parentNode, paths } = getPathNode(tree, currentNode)

  // console.log(parentNode, paths)

  // return false
  const pathLast = paths[paths.length - 1]

  const nodesNumber = parentNode.childList.length

  const children = currentNode.node.childList

  const id = genId()
  const type = newNode.type

  const newNodeArr = [{
    id,
    type,
    childList: currentNode.node.childList
  }]

  if (nodesNumber === 1) {
    parentNode.childList[0].childList = newNodeArr
  } else if (nodesNumber > 1) {
    switch (children.length) {
      case 1: {
        parentNode.childList[pathLast].childList = newNodeArr
        break
      }
      default:
    }
  }

  return tree
}

export default {
  findById,
  deleteNode,
  deleteBranch,
  addNode
}
